#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "InetAddr.hpp"

class Reactor;
class Connection
{
public:
    using ptr = std::shared_ptr<Connection>;
    using func_t = std::function<void(Connection::ptr conn)>;
    Connection(int sockfd, uint32_t events, Reactor *R)
        : _sockfd(sockfd), _events(events), _R(R)
    {
    }
    void SetEvent(uint32_t ev)
    {
        _events = ev;
    }
    void SetAddr(struct sockaddr_in &in)
    {
        _addr = in;
    }
    uint32_t Events()
    {
        return _events;
    }
    void RegisterCallback(func_t reader, func_t sender, func_t excepter)
    {
        _reader = reader;
        _sender = sender;
        _excepter = excepter;
    }
    void AddInbuffer(const std::string &buff)
    {
        _inbuffer += buff;
    }
    int SockFd()
    {
        return _sockfd;
    }

    std::string &Inbuffer()
    {
        return _inbuffer;
    }
    std::string &Outbuffer()
    {
        return _outbuffer;
    }
    void AddOutBuffer(const std::string &buff)
    {
        _outbuffer += buff;
    }
    bool InBufferEmpty()
    {
        return _inbuffer.empty();
    }
    bool OutBufferEmpty()
    {
        return _outbuffer.empty();
    }
    void Close()
    {
        if (_sockfd > 0)
        {
            ::close(_sockfd);
        }
    }

    

private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuffer; // 文件描述符对应的读写缓冲区
    std::string _outbuffer;

public:
    func_t _reader;
    func_t _sender;
    func_t _excepter;
    Reactor *_R;
    InetAddr _addr;
};

class ConnectionFactory
{
public:
    static Connection::ptr ListenConnection(int sockfd, uint32_t event, Reactor *r)
    {
        return std::make_shared<Connection>(sockfd, event, r);
    }
};